package com.agileboot.attendance.domain.overtime.service;

import com.agileboot.attendance.common.enums.OvertimeStatusEnum;
import com.agileboot.attendance.domain.overtime.db.entity.AttOvertimeEntity;
import com.agileboot.attendance.domain.overtime.db.service.IOvertimeService;
import com.agileboot.attendance.domain.overtime.dto.OvertimeDTO;
import com.agileboot.attendance.domain.overtime.dto.OvertimeQueryDTO;
import com.agileboot.attendance.domain.overtime.model.OvertimeModel;
import com.agileboot.attendance.domain.overtime.model.OvertimeModelFactory;
import com.agileboot.common.core.page.PageDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 加班申请应用服务
 */
@Service
@RequiredArgsConstructor
public class OvertimeApplicationService {

    private final IOvertimeService overtimeService;
    private final OvertimeModelFactory overtimeModelFactory;

    /**
     * 分页查询加班申请
     *
     * @param queryDTO 查询条件
     * @return 分页结果
     */
    public PageDTO<OvertimeDTO> getPage(OvertimeQueryDTO queryDTO) {
        // 构建查询条件
        LambdaQueryWrapper<AttOvertimeEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(queryDTO.getPersonnelId() != null, AttOvertimeEntity::getEmployeeId, queryDTO.getPersonnelId())
                   .eq(queryDTO.getDeptId() != null, AttOvertimeEntity::getDeptId, queryDTO.getDeptId())
                   .eq(queryDTO.getStatus() != null, AttOvertimeEntity::getStatus, queryDTO.getStatus())
                   .ge(queryDTO.getStartTime() != null, AttOvertimeEntity::getStartTime, queryDTO.getStartTime())
                   .le(queryDTO.getEndTime() != null, AttOvertimeEntity::getEndTime, queryDTO.getEndTime())
                   .orderByDesc(AttOvertimeEntity::getCreateTime);

        // 执行分页查询
        Page<AttOvertimeEntity> page = overtimeService.page(
            new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()),
            queryWrapper
        );

        // 转换为DTO列表
        List<OvertimeDTO> records = page.getRecords().stream()
            .map(entity -> {
                OvertimeDTO dto = new OvertimeDTO();
                BeanUtils.copyProperties(entity, dto);
                return dto;
            }).collect(Collectors.toList());

        // 创建分页DTO
        return new PageDTO<>(records, page.getTotal());
    }

    /**
     * 获取加班申请详情
     *
     * @param overtimeId 加班ID
     * @return 加班申请详情
     */
    public OvertimeDTO getInfo(Long overtimeId) {
        OvertimeModel model = overtimeModelFactory.loadById(overtimeId);
        OvertimeDTO dto = new OvertimeDTO();
        BeanUtils.copyProperties(model, dto);
        return dto;
    }

    /**
     * 提交加班申请
     *
     * @param dto 加班申请信息
     * @return 加班ID
     */
    @Transactional(rollbackFor = Exception.class)
    public Long submit(OvertimeDTO dto) {
        // 创建加班申请
        OvertimeModel model = overtimeModelFactory.create();
        BeanUtils.copyProperties(dto, model);

        // 设置初始状态
        model.setStatus(OvertimeStatusEnum.PENDING.getValue());

        // 验证时间
        model.validateTime();

        // 保存
        overtimeService.save(model);
        return model.getOvertimeId();
    }

    /**
     * 修改加班申请
     *
     * @param dto 加班申请信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(OvertimeDTO dto) {
        // 获取并更新加班申请
        OvertimeModel model = overtimeModelFactory.loadById(dto.getOvertimeId());
        BeanUtils.copyProperties(dto, model);

        // 验证时间
        model.validateTime();

        // 保存
        overtimeService.updateById(model);
    }

    /**
     * 取消加班申请
     *
     * @param overtimeId 加班ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancel(Long overtimeId) {
        // 获取加班申请
        OvertimeModel model = overtimeModelFactory.loadById(overtimeId);

        // 执行取消操作
        model.cancel();

        // 保存
        overtimeService.updateById(model);
    }

    /**
     * 审批加班申请
     *
     * @param overtimeId   加班ID
     * @param approverId   审批人ID
     * @param approverName 审批人姓名
     * @param status      审批状态
     * @param remark      审批备注
     */
    @Transactional(rollbackFor = Exception.class)
    public void approve(Long overtimeId, Long approverId, String approverName, String status, String remark) {
        // 获取加班申请
        OvertimeModel model = overtimeModelFactory.loadById(overtimeId);

        // 根据状态执行相应的审批操作
        if (OvertimeStatusEnum.APPROVED.getValue().equals(status)) {
            model.approve(approverId, approverName, remark);
        } else if (OvertimeStatusEnum.REJECTED.getValue().equals(status)) {
            model.reject(approverId, approverName, remark);
        }

        // 保存
        overtimeService.updateById(model);
    }
}
